package com.aaa.filters;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.aaa.entity.SysUser;
import com.aaa.enums.AuthPermitPathEnum;
import com.aaa.exceptions.CustomException;
import com.aaa.result.Result;
import com.aaa.service.SysUserService;
import com.aaa.utils.AuthPathMatcherUtil;
import com.aaa.utils.JwtUtil;
import com.aaa.utils.RedisUtil;
import com.aaa.utils.ResponseUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author : luoBo
 * 登录需要的过滤器
 */
@Component
public class AuthFilter implements Filter {

    private SysUserService sysUserService;

    private RedisUtil redisUtil;


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        sysUserService = SpringUtil.getBean(SysUserService.class);
        redisUtil = SpringUtil.getBean(RedisUtil.class);
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest)request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        String tokenHeader = httpServletRequest.getHeader("X-token");
        //1、没有token的情况下，看看是否在放行的路径中
        if (StringUtils.isBlank(tokenHeader)
                &&!AuthPathMatcherUtil.matchesAny(AuthPermitPathEnum.getAllPatterns(),httpServletRequest.getServletPath())){
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            ResponseUtil.writeError(httpServletResponse,JSONUtil.toJsonStr(Result.error("请登录后再操作")));
            return;
        }
        //2、在有token的情况下，看看登录是否超时
        if (StringUtils.isNotBlank(tokenHeader)
                &&!redisUtil.hasKey(tokenHeader)){
            ResponseUtil.writeError(httpServletResponse,JSONUtil.toJsonStr(Result.error("用户登录时间超时，请重新登录！")));
            return;
        }
        //3、在有token的情况下，看看用户是否被删除,密码修改等一系列操作
        if (StringUtils.isNotBlank(tokenHeader)){
            SysUser sysUser = JSONUtil.toBean(redisUtil.get(tokenHeader), SysUser.class);
            int userCount = sysUserService.count(Wrappers.lambdaQuery(SysUser.class)
                    .eq(SysUser::getUsername, sysUser.getUsername())
                    .eq(SysUser::getPassword, sysUser.getPassword())
                    .eq(SysUser::getDelFlag, 0));
            if (0 == userCount){
                ResponseUtil.writeError(httpServletResponse,JSONUtil.toJsonStr(Result.error("用户登录时间超时，请重新登录！")));
                return;
            }
        }
        chain.doFilter(request,response);
    }
}
